package org.white.word2pdf.utils;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.util.ObjectUtils;

/**
 * @author zengle.huang@hand-china.com
 * @version 1.0
 * @description PDF方法类
 * @date 2017/8/22
 * @name MatrixToImageWriter
 */
public class PdfUtil {

    private static String ONLYOFFICE_CONVERT_URL = "http://117.78.34.199:8000/ConvertService.ashx";

    public static byte[] readFile(String name) throws IOException {
        File f = new File("word/" + name + ".docx");
        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
    }

    public static float word2pdfDocx4j(String name) {
        try {
            byte[] byteArr = readFile(name);
            InputStream is = new ByteArrayInputStream(byteArr);
            long startTime=System.currentTimeMillis();
            WordprocessingMLPackage word = WordprocessingMLPackage.load(is);
            Mapper fontMapper = new IdentityPlusMapper();
            fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
            fontMapper.put("黑体",PhysicalFonts.get("SimHei"));
            fontMapper.put("楷体",PhysicalFonts.get("KaiTi"));
            fontMapper.put("新宋体",PhysicalFonts.get("NSimSun"));
            fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));

            word.setFontMapper(fontMapper);
            FOSettings foSettings = Docx4J.createFOSettings();
            foSettings.setWmlPackage(word);
            FileOutputStream os = new FileOutputStream("pdf/docx4j-" + name + ".pdf");
            Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
            os.close();
            long endTime=System.currentTimeMillis();
            float excTime=(float)(endTime-startTime)/1000;
            System.out.println("执行时间："+excTime+"s");
            return excTime;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Docx4JException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0F;
    }

    public static float word2pdfAspose(String name) {
        try {
            byte[] byteArr = readFile(name);
            InputStream is = new ByteArrayInputStream(byteArr);
            long startTime=System.currentTimeMillis();
            Document doc = new Document(is);
            FileOutputStream pdfOut = new FileOutputStream("pdf/aspose-" + name + ".pdf");
            //接受修订
            doc.acceptAllRevisions();
            //去掉评论
            /*NodeCollection comments = doc.getChildNodes(NodeType.COMMENT, true);
            comments.clear();*/
            doc.save(pdfOut, SaveFormat.PDF);
            long endTime=System.currentTimeMillis();
            float excTime=(float)(endTime-startTime)/1000;
            System.out.println("执行时间："+excTime+"s");
            is.close();
            pdfOut.close();
            return excTime;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Docx4JException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0F;
    }

    private static byte[] downloadFileByUrl(String downStr) {
        URL downUrl = null;
        InputStream inputStream = null;
        try {
            downUrl = new URL(downStr);
            HttpURLConnection conn = (HttpURLConnection)downUrl.openConnection();
            //设置超时间为3分钟
            conn.setConnectTimeout(3 * 60 *1000);
            conn.setReadTimeout(3 * 60 *1000);
            inputStream = conn.getInputStream();
            byte[] fileData = readInputStream(inputStream);
            return fileData;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

        return null;
    }

    private static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        IOUtils.closeQuietly(bos);
        return bos.toByteArray();
    }

    public static float word2pdfOnlfyoffice(String name){
        long startTime=System.currentTimeMillis();
        String downloadFileUrl = "http://localhost:8035/fms/word/"+name;
        Map<String, Object> param = new HashMap<>();
        param.put("async", "false");
        param.put("filetype", "docx");
        String key = RandomStringUtils.randomAlphanumeric(10);
        param.put("key", key);
        param.put("outputtype", "pdf");
        param.put("title", "Test.docx");
        param.put("url", downloadFileUrl);

        Map<String, String> headerParam = new HashMap<>();
        //发送转换请求
        String result = HttpUtil.sendGet(ONLYOFFICE_CONVERT_URL, param, headerParam);
        //返回的result为xml格式，使用dom4j解析
        try {
            org.dom4j.Document document = DocumentHelper.parseText(result);
            Element fileResult = document.getRootElement();
            Element fileUrlElement = fileResult.element("FileUrl");
            if (ObjectUtils.isEmpty(fileUrlElement)) {
                Element errorElement = fileResult.element("Error");
                String errorCode = errorElement.getText();
                //此处发生异常，根据code返回错误，报错给前台
            }
            //还有其他的属性，如果要用的话看看官网
            String fileUrl = fileUrlElement.getText();
            //filebyes为转换后的文件字节
            byte[] filebyes = downloadFileByUrl(fileUrl);
            long endTime=System.currentTimeMillis();
            float excTime=(float)(endTime-startTime)/1000;
            System.out.println("从发送请求到下载文件的执行时间："+excTime+"s");
            FileOutputStream pdfOut = new FileOutputStream("pdf/onlyoffice-" + name + ".pdf");
            pdfOut.write(filebyes,0,filebyes.length);
            pdfOut.flush();
            pdfOut.close();
            return excTime;
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return 0F;
    }

}
